/**
 * 跨域配置与Web服务器配置类
 *
 * 功能概述：
 * • 配置CORS跨域资源共享策略，支持前后端分离架构
 * • 自定义Tomcat服务器配置，处理特殊字符路径和查询参数
 * • 提供双重CORS配置机制（注解配置和过滤器配置）
 *
 * 跨域配置特性：
 * • 支持所有源地址访问（生产环境建议指定具体域名）
 * • 允许常见HTTP方法（GET、POST、PUT、DELETE）
 * • 启用凭证传输（Cookie、Authorization头部）
 * • 暴露自定义响应头部（Authorization）
 *
 * 服务器配置：
 * • 放宽URL路径字符限制，支持特殊符号
 * • 放宽查询参数字符限制，增强兼容性
 * • 确保特殊字符在URL中的正确传输和处理
 *
 * 安全考虑：
 * • 预检请求缓存时间设置（1小时）
 * • 过滤器优先级设置为最高，确保最先执行
 * • 生产环境建议限制allowedOriginPatterns为具体域名
 */
package com.example.mangroves.config;

import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")//允许跨域访问的路径(控制器的路径)
                .allowedOriginPatterns("*")//允许跨域访问的源(前端的路径)
                .allowedMethods("GET", "POST", "PUT", "DELETE")//允许前端发送的请求
                .maxAge(168000)//预检间隔时间
                .allowedHeaders("*")//允许头部设置
                .allowCredentials(true)//是否发送cookie
                .maxAge(3600)
                .exposedHeaders("Authorization");
    }

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);
        config.setMaxAge(3600L);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }

    @Bean
    public TomcatServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers((Connector connector) -> {
            connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
            connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
        });
        return factory;
    }

}

